/* eslint-disable no-unused-vars */

import VectorLayer from 'ol/layer/Vector';
import { Circle as CircleStyle, Fill, Stroke, Style, RegularShape, Text, Icon } from 'ol/style';
import VectorSource from 'ol/source/Vector';
import GeoJSON from 'ol/format/GeoJSON';
import { Point, LineString, Polygon } from 'ol/geom';
import Overlay from 'ol/Overlay';
import Draw from 'ol/interaction/Draw'
import { unByKey } from 'ol/Observable';
import { getArea, getLength } from 'ol/sphere';
// js
import { transformLineForPoint, transformLonlatToNow, transformNowToLonlat, CalculationAngle, getCenterPoint } from "/@/views/monitor/components/map/js/util"

const LayerZIndex = {
  radius: 202, // 船舶选中框
  ship: 220, // 本船队
  otherShip: 210, // 他船队
  wave: 203, // 尾迹
  line: 205, // 航线
  trajectory: 204, // 船舶轨迹
  draw: 201, // 测绘
  alarm: 202, // 电子围栏
  sign: 203, // 标记
  weather: 210, // 气象、台风
  typhoon: 211, // 台风动画
  mob: 203, // mob报警
  shareInfo: 205, // 共享信息
  notice: 205, // 航海通告
  aquatic: 204, // 保护区
}


const chartConfig = {
  chartDrawName: "DRAW_LIST",
  shipSettingName: "SHIP_SETTING",
  EPSGCode: "EPSG:3857"
}

// 绘制图形样式
const drawStyle = () => {
  return new Style({
    fill: new Fill({
      color: 'rgba(100, 205, 142, 0.5)'
    }),
    stroke: new Stroke({
      color: 'rgba(255, 255, 255, 1)',
      width: 2
    }),
    image: new CircleStyle({
      radius: 3,
      stroke: new Stroke({
        color: 'rgba(0, 0, 0, 0.7)'
      }),
      fill: new Fill({
        color: 'rgba(255, 255, 255, 0.2)'
      })
    })
  })
}

// 测绘图形中点的样式
function drawStyleFn(feature) {
  let styleList = [drawStyle()]
  const coordinatesType = feature.getGeometry().getType();
  if (coordinatesType === "Circle") return styleList
  const Coordinates = feature.getGeometry().getCoordinates();
  let list = coordinatesType === "Polygon" ? Coordinates[0] : Coordinates;
  const colors = ["#88FF88", "#FFFFFF", "#D53645"];
  var fn = (row, index = 1) => {
    styleList.push(
      new Style({
        zIndex: 10,
        image: new CircleStyle({
          radius: 3.5,
          fill: new Fill({
            color: colors[index],
          }),
          stroke: new Stroke({
            color: "#333333",
            width: 1.5,
          }),
        }),
        geometry: new Point(row),
      })
    );
  };
  if (coordinatesType === "Polygon") {
    list = list.slice(0, list.length - 1);
  }
  for (let item of list.slice(1, list.length - 1)) {
    fn(item, 1);
  }
  fn(list[0], 0);
  fn(list[list.length - 1], 2);
  return styleList;
}

// 绘制时的样式
const measureStyle = () => {
  return new Style({
    fill: new Fill({
      color: 'rgba(255, 255, 255, 0.2)'
    }),
    stroke: new Stroke({
      color: 'rgba(255, 255, 255, 1)',
      lineDash: [10, 10],
      width: 3
    }),
    image: new CircleStyle({
      radius: 3,
      stroke: new Stroke({
        color: 'rgba(0, 0, 0, 0.7)'
      }),
      fill: new Fill({
        color: 'rgba(255, 255, 255, 0.2)'
      })
    })
  })
}
// 面积
const formatArea = (polygon) => {
  var area = getArea(polygon, {
    radius: 6378137,
    projection: "EPSG:3857"
  });
  var output;
  if (area > 10000) {
    output = (Math.round(area / 1000000 * 100) / 100) +
      ' ' + 'km<sup>2</sup>';
  } else {
    output = (Math.round(area * 100) / 100) +
      ' ' + 'm<sup>2</sup>';
  }
  return output;
}
var nMile = 1852

// 长度对象
// 长度
const formatLength = (line) => {
  var length = getLength(line, {
    radius: 6378137,
    projection: "EPSG:3857"
  });
  // const nm = (length / nMile).toFixed(3) + "nm"
  const m = length.toFixed(3) + "m"
  return m;
}

// 长度对象
const formatLengthForUtil = (line) => {
  var length = getLength(line, {
    radius: 6378137,
    projection: chartConfig.EPSGCode
  });
  // const nm = (length / nMile).toFixed(3)
  const m = length.toFixed(3) + "m"
  return {
    length: m,
    output: m + "m",
  };
}

function getCoordinate(list) {
  let x = 0, y = 0;
  let length = list.length
  length = length === 2 ? 2 : length - 1
  for (let index = 0; index < length; ++index) {
    x += list[index][0]
    y += list[index][1]
  }
  return [
    x / length,
    y / length
  ]
}

const areaStyleFn = (feature) => {
  let list = []
  list.push(
    new Style({
      fill: new Fill({
        color: `rgba(213, 120, 170, 0.2)`,
      }),
      stroke: new Stroke({
        color: `rgba(213, 120, 170, 1)`,
        width: 1.5
      }),
    })
  )
  const lonAndLat = feature.values_.pointList.map(m => transformLonlatToNow([m.lon, m.lat]))
  const centerPoint = getCenterPoint(lonAndLat)
  list.push(
    new Style({
      zIndex: 10,
      text: new Text({
        text: feature.values_.name,
        font: '30px sans-serif',
        fill: new Fill({
          color: "rgba(0, 0, 0, 0.5)",
        }),
      }),
      geometry: new Point(centerPoint),
    })
  );
  return list
}

export default {
  // 测绘
  measure: (map, measureType) => {
    console.log("map: ", map)
    // 创建一个当前要绘制的对象
    var sketch;
    // 创建一个帮助提示框对象
    var helpTooltipElement;
    // 创建一个帮助提示信息对象
    var helpTooltip;
    // 创建一个测量提示框对象
    var measureTooltipElement;
    // 创建一个测量提示信息对象
    var measureTooltip;
    // 继续绘制多边形的提示信息
    var continuePolygonMsg = '双击结束绘制';
    // 继续绘制线段的提示信息
    var continueLineMsg = '双击结束绘制';
    // 创建两个提示框实例
    createMeasureTooltip();
    createHelpTooltip();

    // 绑定鼠标事件
    var pointerMoveHandler = function (evt) {
      if (evt.dragging) {
        return;
      }
      /** @type {string} */
      var helpMsg = '请点击开始绘制';

      if (sketch) {
        var geom = (sketch.getGeometry());
        if (geom instanceof Polygon) {
          helpMsg = continuePolygonMsg;
        } else if (geom instanceof LineString) {
          helpMsg = continueLineMsg;
        }
      }
      helpTooltipElement.innerHTML = helpMsg;
      helpTooltip.setPosition(evt.coordinate);
      helpTooltipElement.classList.remove('hidden');
    };

    // 添加鼠标事件
    map.on('pointermove', pointerMoveHandler);
    map.getViewport().addEventListener('mouseout', function () {
      helpTooltipElement.classList.add('hidden');
    });

    var draw;
    var source;
    var layerTmp = map.getLayers().getArray().find(m => m.get("name") === "DRAW")
    if (!layerTmp) {
      layerTmp = new VectorLayer({
        source: new VectorSource({
          features: [],
        }),
        zIndex: LayerZIndex.draw,
        name: "DRAW",
        style: drawStyleFn
      });
      map.addLayer(layerTmp)
    }
    source = layerTmp.getSource();

    // 图形样式
    draw = new Draw({
      source: source,
      type: measureType == 'area' ? 'Polygon' : 'LineString',
      style: measureStyle
    })

    function addInteraction() {
      map.addInteraction(draw);

      var listener;
      var output;
      var type;
      draw.on('drawstart',
        function (evt) {
          // set sketch
          sketch = evt.feature;

          /** @type {module:ol/coordinate~Coordinate|undefined} */
          var tooltipCoord = evt.coordinate;

          listener = sketch.getGeometry().on('change', function (evt) {
            var geom = evt.target;
            if (geom instanceof Polygon) {
              output = formatArea(geom);
              tooltipCoord = geom.getInteriorPoint().getCoordinates();
              type = "Polygon"
            } else if (geom instanceof LineString) {
              output = formatLength(geom);
              tooltipCoord = geom.getLastCoordinate();
              type = "LineString"
            }
            measureTooltipElement.innerHTML = output;
            measureTooltip.setPosition(tooltipCoord);
          });
        }, this);

      draw.on('drawend',
        function (e) {
          measureTooltipElement.className = 'draw-tooltip tooltip-static';
          measureTooltip.setOffset([0, -7]);
          sketch = null;
          measureTooltipElement = null;
          createMeasureTooltip();
          // 移除事件监听
          unByKey(listener);
          map.un('pointermove', pointerMoveHandler);
          // 获取坐标点，并存入local中
          const geometry = e.feature.getGeometry()
          let corrdinates = geometry.getCoordinates()
          if (corrdinates.length === 1) {
            corrdinates = corrdinates[0]
          }
          // 移除地图单击事件
          map.removeInteraction(draw);
          helpTooltipElement.classList.add('hidden');
        }, this);
    }

    // 将帮助提示语添加到图层中
    function createHelpTooltip() {
      if (helpTooltipElement) {
        helpTooltipElement.parentNode.removeChild(helpTooltipElement);
      }
      helpTooltipElement = document.createElement('div');
      helpTooltipElement.className = 'tooltip hidden';
      helpTooltip = new Overlay({
        element: helpTooltipElement,
        offset: [15, 0],
        positioning: 'center-left'
      });
      map.addOverlay(helpTooltip);
    }

    // 将提示语添加到图层中
    function createMeasureTooltip() {
      if (measureTooltipElement) {
        measureTooltipElement.parentNode.removeChild(measureTooltipElement);
      }
      measureTooltipElement = document.createElement('div');
      measureTooltipElement.className = 'tooltip tooltip-measure';
      measureTooltip = new Overlay({
        element: measureTooltipElement,
        offset: [0, -15],
        positioning: 'bottom-center'
      });
      map.addOverlay(measureTooltip);
    }
    // 量测调用
    addInteraction();
  },
  // 复现local storage中的历史绘制数据
  reappearance: (map, list) => {
    var geojsonObject = {
      type: 'FeatureCollection',
      crs: {
        type: 'name',
        properties: {
          name: chartConfig.EPSGCode
        }
      },
      features: []
    };
    var CirculList = []
    for (const item of list) {
      // 将坐标点放入geo中
      if (item.type === "ERBL") { // ERBL
        CirculList.push(item)
        geojsonObject.features.push(
          {
            type: 'Feature',
            geometry: {
              type: "LineString",
              coordinates: item.list
            }
          }
        )
      } else { // Polygon || LineString
        geojsonObject.features.push(
          {
            type: 'Feature',
            geometry: {
              type: item.type,
              coordinates: item.type === 'Polygon' ? [item.list] : item.list
            }
          }
        )

      }
      // 计算长度或面积，加入ele
      let measureTooltipElement = document.createElement('div');
      measureTooltipElement.className = 'draw-tooltip tooltip-measure';
      let measureTooltip = new Overlay({
        element: measureTooltipElement,
        offset: [0, 0],
        positioning: 'bottom-center'
      });
      map.addOverlay(measureTooltip);
      measureTooltipElement.innerHTML = item.output;
      if (item.type === 'Polygon') {
        measureTooltip.setPosition(getCoordinate(item.list));
      } else {
        measureTooltip.setPosition(item.list[item.list.length - 1]);
      }
    }
    var source = new VectorSource({
      features: (new GeoJSON()).readFeatures(geojsonObject)
    });
    // for (let index in CirculList) {
    //   const item = CirculList[index]
    //   var CircleBeta = new Feature({
    //     geometry: new Circle(item.list[0], parseFloat(item.util.length))
    //   })
    //   source.addFeature(CircleBeta);
    // }
    let layerTmp = map.getLayers().getArray().find(m => m.get("name") === "DRAW")
    if (!layerTmp) {
      layerTmp = new VectorLayer({
        source: new VectorSource({
          features: [],
        }),
        zIndex: LayerZIndex.draw,
        name: "DRAW",
        style: drawStyleFn
      });
      map.addLayer(layerTmp)
    }
    layerTmp.setSource(source)
  },
  // ERBL
  measureERBL: (map) => {
    // 实例
    var sketch;
    // 信息对象
    var measureTooltipElement;
    // 信息实例
    var measureTooltip;
    var pointerMoveHandler = function (evt) {
      if (evt.dragging) {
        return;
      }
    };
    // 创建实例
    createMeasureTooltip();

    // 添加鼠标事件
    map.on('pointermove', pointerMoveHandler);

    var CircleDraw;
    var lineDraw;
    var source;
    var layerTmp = map.getLayers().getArray().find(m => m.get("name") === "DRAW")
    if (!layerTmp) {
      layerTmp = new VectorLayer({
        source: new VectorSource({
          features: [],
        }),
        zIndex: LayerZIndex.draw,
        name: "DRAW",
        style: drawStyle
      });
      map.addLayer(layerTmp)
    }
    source = layerTmp.getSource();

    // 图形样式
    CircleDraw = new Draw({
      source: source,
      type: "Circle",
      style: measureStyle
    })
    lineDraw = new Draw({
      source: source,
      type: "LineString",
      style: measureStyle
    })

    function addInteraction() {
      var msg = "";
      var util = {};
      var point = [];
      map.addInteraction(CircleDraw);
      map.addInteraction(lineDraw);

      var listener;
      lineDraw.on('drawstart',
        function (evt) {
          // set sketch
          sketch = evt.feature;
          let corrdinates;
          var tooltipCoord = evt.coordinate;

          /** @type {module:ol/coordinate~Coordinate|undefined} */

          listener = sketch.getGeometry().on('change', function (evt) {
            var geom = evt.target;
            const geometry = sketch.getGeometry()
            tooltipCoord = geom.getLastCoordinate();
            corrdinates = geometry.getCoordinates()
            point = corrdinates.slice(0, 2).map(m => transformNowToLonlat(m))
            // 角度
            const drawData = CalculationAngle(point)
            // 距离
            util = formatLengthForUtil(geom);
            msg = `ERBL: ${util.output}  ${drawData}°`;
            measureTooltipElement.innerHTML = msg
            measureTooltip.setPosition(tooltipCoord);
            if (corrdinates.length >= 3) {
              setTimeout(() => {
                lineDraw.finishDrawing()
              }, 0);
            }
          });
        }, this);

      lineDraw.on('drawend',
        function () {
          sketch = null;
          // 移除事件监听
          unByKey(listener);
          map.un('pointermove', pointerMoveHandler);
          // 坐标点local存储
          // let list = getStore({
          //   name: chartConfig.chartDrawName,
          // })
          // const row = {
          //   type: "ERBL",
          //   output: msg,
          //   util: util,
          //   list: point
          // }
          // if (!list) {
          //   list = [row]
          // } else {
          //   list.push(row)
          // }
          // setStore({
          //   name: chartConfig.chartDrawName,
          //   content: list
          // })
          // 移除地图单击事件
          map.removeInteraction(CircleDraw);
          map.removeInteraction(lineDraw);
        }, this);
    }
    function createMeasureTooltip() {
      if (measureTooltipElement) {
        measureTooltipElement.parentNode.removeChild(measureTooltipElement);
      }
      measureTooltipElement = document.createElement('div');
      measureTooltipElement.className = 'draw-tooltip tooltip-measure';
      measureTooltip = new Overlay({
        element: measureTooltipElement,
        offset: [0, -15],
        positioning: 'bottom-center'
      });
      map.addOverlay(measureTooltip);
    }

    addInteraction()
  },
  // 清空绘制
  handleClearDraw: (layerTmp, map) => {
    if (layerTmp.getSource()) {
      layerTmp.getSource().clear()
    }
    map.removeLayer(layerTmp)
    var Drawom = document.getElementsByClassName("draw-tooltip");
    for (let i = Drawom.length - 1; i >= 0; --i) {
      if (Drawom[i] != null) Drawom[i].parentNode.removeChild(Drawom[i]);
    }
    // removeStore({
    //   name: chartConfig.chartDrawName,
    // });
  },
  // 标记
  drawSign: (map) => {
    return new Promise(resolve => {
      var helpTooltipElement;
      var helpTooltip;
      // 创建两个提示框实例
      createHelpTooltip();
      var pointerMoveHandler = function (evt) {
        if (evt.dragging) {
          return;
        }
        var helpMsg = '点击获取坐标';
        helpTooltipElement.innerHTML = helpMsg;
        helpTooltip.setPosition(evt.coordinate);
        helpTooltipElement.classList.remove('hidden');
      };
      var clickHandler = function (evt) {
        if (evt.dragging) {
          return;
        }
        createSignTool(transformNowToLonlat(evt.coordinate))
        map.un('pointermove', pointerMoveHandler);
        map.un('click', clickHandler);
      };

      // 添加鼠标事件
      map.on('pointermove', pointerMoveHandler);
      map.on('click', clickHandler);

      function createSignTool(coordinate) {
        helpTooltipElement.parentNode.removeChild(helpTooltipElement);
        resolve(coordinate)
      }

      function createHelpTooltip() {
        if (helpTooltipElement) {
          helpTooltipElement.parentNode.removeChild(helpTooltipElement);
        }
        helpTooltipElement = document.createElement('div');
        helpTooltipElement.className = 'tooltip hidden';
        helpTooltip = new Overlay({
          element: helpTooltipElement,
          offset: [15, 0],
          positioning: 'center-left'
        });
        map.addOverlay(helpTooltip);
      }
    })
  },
  // 复现标记
  reappearanceSign: (map, data) => {
    var geojsonObject = {
      type: 'FeatureCollection',
      crs: {
        type: 'name',
        properties: {
          name: chartConfig.EPSGCode
        }
      },
      features: []
    };
    for (let item of data) {
      geojsonObject.features.push(
        {
          type: 'Feature',
          geometry: {
            type: "Point",
            coordinates: transformLonlatToNow([item.lon, item.lat])
          },
          properties: item
        }
      )
    }
    const setMapStyle = (feature) => {
      let styleList = []
      const Coordinates = feature.getGeometry().getCoordinates();
      styleList.push(new Style({
        zIndex: LayerZIndex.sign,
        image: new Icon({
          src: "/img/chart/point.png",
          color: "#d4237a"
        }),
        text: new Text({
          text: feature.values_.name,
          font: '14px sans-serif',
          fill: new Fill({
            color: "#000066",
          }),
          offsetX: 0,
          offsetY: 15,
        }),
        geometry: new Point(Coordinates)
      }))
      return styleList
    }
    var source = new VectorSource({
      features: (new GeoJSON()).readFeatures(geojsonObject)
    });
    let layerTmp = map.getLayers().getArray().find(m => m.get("name") === "SIGN")
    if (layerTmp) map.removeLayer(layerTmp)
    layerTmp = new VectorLayer({
      source: source,
      zIndex: LayerZIndex.sign,
      name: "SIGN",
      style: setMapStyle
    });
    map.addLayer(layerTmp)

  },
  // 区域绘制
  drawAlarm: (map) => {
    return new Promise(resolve => {
      var sketch;
      var helpTooltipElement;
      var helpTooltip;
      var continuePolygonMsg = '双击结束绘制';
      var continueLineMsg = '双击结束绘制';
      createHelpTooltip();
      var pointerMoveHandler = function (evt) {
        if (evt.dragging) {
          return;
        }
        /** @type {string} */
        var helpMsg = '请点击开始绘制';

        if (sketch) {
          var geom = (sketch.getGeometry());
          if (geom instanceof Polygon) {
            helpMsg = continuePolygonMsg;
          } else if (geom instanceof LineString) {
            helpMsg = continueLineMsg;
          }
        }
        helpTooltipElement.innerHTML = helpMsg;
        helpTooltip.setPosition(evt.coordinate);
        helpTooltipElement.classList.remove('hidden');
      };

      // 添加鼠标事件
      map.on('pointermove', pointerMoveHandler);
      map.getViewport().addEventListener('mouseout', function () {
        helpTooltipElement.classList.add('hidden');
      });

      var draw;
      var source;
      let layerTmp = map.getLayers().getArray().find(m => m.get("name") === "ALARM")
      if (!layerTmp) {
        layerTmp = new VectorLayer({
          source: new VectorSource({
            features: [],
          }),
          zIndex: LayerZIndex.alarm,
          name: "ALARM",
        });
        map.addLayer(layerTmp)
      }
      source = layerTmp.getSource();

      // 将帮助提示语添加到图层中
      function createHelpTooltip() {
        if (helpTooltipElement) {
          helpTooltipElement.parentNode.removeChild(helpTooltipElement);
        }
        helpTooltipElement = document.createElement('div');
        helpTooltipElement.className = 'tooltip hidden';
        helpTooltip = new Overlay({
          element: helpTooltipElement,
          offset: [15, 0],
          positioning: 'center-left'
        });
        map.addOverlay(helpTooltip);
      }

      // 图形样式
      draw = new Draw({
        source: source,
        type: "Polygon",
        style: measureStyle
      })
      map.addInteraction(draw);

      var listener;
      draw.on('drawstart',
        function (evt) {
          sketch = evt.feature;
        }, this);

      draw.on('drawend',
        function (e) {
          sketch = null;
          // 移除事件监听
          unByKey(listener);
          map.un('pointermove', pointerMoveHandler);
          const geometry = e.feature.getGeometry()
          let corrdinates = geometry.getCoordinates()
          if (corrdinates.length === 1) {
            corrdinates = corrdinates[0]
          }
          corrdinates = corrdinates.map(m => transformNowToLonlat(m))
          // 移除地图单击事件
          map.removeInteraction(draw);
          helpTooltipElement.classList.add('hidden');
          // 返回数据
          resolve(corrdinates)
        }, this);
    })
  },
  // 复现区域绘制
  drawAlarmRegion: (map, data) => {
    var geojsonObject = {
      type: 'FeatureCollection',
      crs: {
        type: 'name',
        properties: {
          name: 'EPSG: 3857'
        }
      },
      features: []
    };
    for (const index in data) {
      let item = data[index]
      item.index = index
      const list = item.pointList.map(m => {
        return transformLonlatToNow([m.lon, m.lat])
      })
      // 将坐标点放入geo中
      geojsonObject.features.push(
        {
          type: 'Feature',
          geometry: {
            type: "Polygon",
            coordinates: [list],
          },
          properties: item
        }
      )
    }
    var source = new VectorSource({
      features: (new GeoJSON()).readFeatures(geojsonObject)
    });
    let layerTmp = map.getLayers().getArray().find(m => m.get("name") === "ALARM")
    if (layerTmp) map.removeLayer(layerTmp)
    layerTmp = new VectorLayer({
      source: source,
      zIndex: LayerZIndex.alarm,
      name: "ALARM",
      style: areaStyleFn
    });
    map.addLayer(layerTmp)
  },
}
